#include "httphelper.h"
#include <QDebug>
#include <QJsonArray>
#include <QJsonDocument>
#include <QJsonObject>
#include <QJsonValue>
#include <mutex>

std::unique_ptr<HttpHelper> HttpHelper::instance_ = nullptr;
#define SERNER_URL "http:/10.200.14.253:8083/"

HttpHelper *HttpHelper::instance()
{
    static std::once_flag flag;
    std::call_once(flag,[&](){
        instance_.reset(new HttpHelper () );
    });
    return instance_.get();
}

HttpHelper::~HttpHelper()
{
    if(networkMannager)
    {
        delete networkMannager;
    }
}

void HttpHelper::slot_GetmadiaInfo()
{
    sendRequest(MEDIALIST,false);
}

void HttpHelper::slot_Register(const QVariantMap &infomap)
{
    QJsonObject paramoObj;
    paramoObj[""] = QJsonObject();
    QJsonObject rootObj;
    rootObj["createTime"] = "";
    rootObj["updateTime"] = "";
    rootObj["params"] = paramoObj;
    rootObj["userId"] = 0;
    rootObj["userName"] = infomap["userName"].toString();
    rootObj["nickName"] = infomap["nickName"].toString();
    rootObj["passwd"] = infomap["passwd"].toString();
    //qjsonobject转为qjsondocument
    QJsonDocument doc(rootObj);
    QByteArray jsondata = doc.toJson(QJsonDocument::Compact);
    sendRequest(REGISTER,true,jsondata);
}

void HttpHelper::slot_Login(const QVariantMap &infomap)
{
    QJsonObject paramoObj;
    paramoObj[""] = QJsonObject();
    QJsonObject rootObj;
    rootObj["createTime"] = "";
    rootObj["updateTime"] = "";
    rootObj["params"] = paramoObj;
    rootObj["userId"] = 0;
    rootObj["userName"] = infomap["userName"].toString();
    rootObj["nickName"] = infomap["nickName"].toString();
    rootObj["passwd"] = infomap["passwd"].toString();
    //qjsonobject转为qjsondocument
    QJsonDocument doc(rootObj);
    QByteArray jsondata = doc.toJson(QJsonDocument::Compact);
    sendRequest(LOGIN,true,jsondata);
}

void HttpHelper::slot_LoginOut(const QVariantMap &infomap)
{
    QJsonObject rootObj;
    QJsonDocument doc(rootObj);
    QByteArray jsondata = doc.toJson(QJsonDocument::Compact);
    sendRequest(LOGINOUT,true,jsondata);
}

void HttpHelper::slot_AddmediaInfo(const QVariantMap &infomap)
{
    QJsonObject paramoObj;
    paramoObj[""] = QJsonObject();
    QJsonObject rootObj;
    rootObj["createTime"] = "";
    rootObj["updateTime"] = "";
    rootObj["params"] = paramoObj;
    rootObj["mediaId"] = 0;
    rootObj["userId"] = 0; // 用户 ID（默认 0）
    rootObj["mediaUrl"] = infomap["mediaUrl"].toString();
    rootObj["mediaTirle"] = infomap["mediaTirle"].toString();
    rootObj["orderNum"] = 0;
    //qjsonobject转为qjsondocument
    QJsonDocument doc(rootObj);
    QByteArray jsondata = doc.toJson(QJsonDocument::Compact);// 紧凑格式（无换行）
    sendRequest(ADDMEDIA,true,jsondata);// 发送请求
}

void HttpHelper::slot_EditmediaInfo(const QVariantMap &infomap)
{

}

void HttpHelper::slot_RemovemediaInfo(const QVariantMap &infomap)
{
    QJsonObject paramoObj;
    paramoObj[""] = QJsonObject();
    QJsonObject rootObj;
    rootObj["createTime"] = "";
    rootObj["updateTime"] = "";
    rootObj["params"] = paramoObj;
    rootObj["userId"] = 0;
    rootObj["userName"] = infomap["userName"].toString();
    rootObj["nickName"] = infomap["nickName"].toString();
    rootObj["passwd"] = infomap["passwd"].toString();
    //qjsonobject转为qjsondocument
    QJsonDocument doc(rootObj);
    QByteArray jsondata = doc.toJson(QJsonDocument::Compact);
    sendRequest(REMOVEEDIT,true,jsondata);
}

void HttpHelper::HandleReply(const QByteArray &data)
{
    QJsonParseError parseError;
    QJsonDocument jsonDoc = QJsonDocument::fromJson(data,&parseError);
    QByteArray jsonstring = jsonDoc.toJson(QJsonDocument::Indented);
    qDebug() <<"json data:"<<jsonstring.constData();
    //检查解析是否有误
    if(parseError.error != QJsonParseError::NoError)
    {
        qDebug() << "JSON解析出错："<<parseError.errorString()<<"位置："<<parseError.offset;
        return;
    }
    //
    if(jsonDoc.isObject())
    {
        QJsonObject jsonObj = jsonDoc.object();
        bool operationSuccess = (jsonObj["code"].toInt() == 200);
        int responseType = jsonObj["responseType"].toInt();
        if(responseType != MEDIALIST)
        {
            if(responseType == LOGIN && operationSuccess)
            {
                token = jsonObj["msg"].toString();
            }
            emit sig_Operator(static_cast<REQUESTTYPE>(responseType),operationSuccess);
        }
        else if(responseType == MEDIALIST && operationSuccess)
        {
            QJsonValue dataValue = jsonObj["data"];
            //检查data是否为数组
            QVector<QVariantMap> madiaList;
            if(dataValue.isArray())
            {
                QJsonArray dataArray = dataValue.toArray();
                //遍历数组提取里面的视频url和title
                for(const QJsonValue &itemValue :dataArray)
                {
                    if(itemValue.isObject())
                    {
                        QJsonObject itemObj = itemValue.toObject();
                        QVariantMap mediaItem;
                        if(itemObj.contains("mediaTitle") && itemObj["mediaTitle"].isString())
                        {
                            mediaItem["mediaTitle"] = itemObj["mediaTitle"].toString();
                        }
                        if(itemObj.contains("mediaUrl") && itemObj["mediaUrl"].isString())
                        {
                            mediaItem["mediaUrl"] = itemObj["mediaUrl"].toString();
                        }
                        madiaList.append(mediaItem);
                    }
                }
            }
            emit sig_Mediainfo(madiaList);
        }
        if(!operationSuccess)
        {
            qDebug()<<"操作失败："<< jsonObj["msg"].toString();
        }
    }
}

void HttpHelper::onReplyFinished(QNetworkReply *reply)
{
    //获取HTTP状态码
    QVariant statusCode = reply->attribute(QNetworkRequest::HttpStatusCodeAttribute);
    //获取详细错误
    QNetworkReply::NetworkError errorType = reply->error();
    QString errorMsg = reply->errorString();
    qDebug() << "request URL:" <<reply->url().toString();
    qDebug() << "HTTP status code" <<statusCode.toInt();
    qDebug() << "Error Type:" << errorType;
    qDebug() << "Error Message:" << errorMsg;

    QByteArray response = reply->readAll();
    qDebug() << "response data:" << QString::fromUtf8(response);

    if(errorType == QNetworkReply::NoError)
    {
        //处理应答
        HandleReply(response);
    }
    else
    {
        switch (errorType) {
        case QNetworkReply::ProxyConnectionRefusedError:
            qDebug()<<"连接拒绝，服务都未安装或者端口未开放";
            break;
        case QNetworkReply::HostNotFoundError:
            qDebug()<<"主机未找到，IP或者DNS错误";
            break;
        case QNetworkReply::TimeoutError:
             qDebug()<<"请求超时";
            break;
        case QNetworkReply::ContentNotFoundError:
            qDebug()<<"连接没有找到，URL错误";
            break;
        default:
            qDebug()<<"其他错误"<<errorMsg;
        }
    }
    reply->deleteLater();

}

void HttpHelper::sendGetRequest(const QNetworkRequest &request)
{
    networkMannager->get(request);
}

void HttpHelper::sendPostRequest(QNetworkRequest &request, const QByteArray &data)
{
    networkMannager->post(request,data);
}
#include<QUrl>

void HttpHelper::sendRequest(const REQUESTTYPE type, bool isPost, const QByteArray data)
{
    QUrl url = QUrl::fromUserInput(requestAddrs[type]);
    if(!url.isValid())
    {
        qDebug()<<"url无效";
        return;
    }
    QNetworkRequest request(url);
    //指定数据为json
    request.setHeader(QNetworkRequest::ContentTypeHeader,"application/json");
    //设置token
    QByteArray authHeader = token.toUtf8();
    request.setRawHeader("Authorization",authHeader);
    isPost ? sendPostRequest(request,data) : sendGetRequest(request);
}

HttpHelper::HttpHelper(QObject *parent)
    : QObject(parent)
    ,networkMannager(new QNetworkAccessManager(this))//初始化列表
{
     requestAddrs[REGISTER] = QString(SERNER_URL) + "user/register";
     requestAddrs[LOGIN] = QString(SERNER_URL) + "user/login";
     requestAddrs[LOGINOUT] = QString(SERNER_URL) + "user/logout";
     requestAddrs[MEDIALIST] = QString(SERNER_URL) + "media/list";
     requestAddrs[ADDMEDIA] = QString(SERNER_URL) + "media/add";
     requestAddrs[EDITMEDIA] = QString(SERNER_URL) + "media/edit";
     requestAddrs[REMOVEEDIT] = QString(SERNER_URL) + "media/remove";

     connect(networkMannager,&QNetworkAccessManager::finished,this,&HttpHelper::onReplyFinished);
}
